#include <iostream>
#include <fstream>      // std::ifstream, std::ofstream :contentReference[oaicite:9]{index=9}
#include <vector>       // std::vector :contentReference[oaicite:10]{index=10}
#include <string>       // std::string, operator+ 
#include <cstdint>      // uint8_t

#ifdef _WIN32
  #include <direct.h>
  #define MKDIR(dir) _mkdir(dir)
#else
  #include <sys/stat.h>
  #include <sys/types.h>
  #define MKDIR(dir) mkdir(dir, 0755)
#endif

int main(int argc, char* argv[]) {
    if (argc != 3) {
        std::cerr << "Usage: " << argv[0]
                  << " <input_file> <output_dir>\n";
        return 1;
    }
    std::string input_file = argv[1];
    std::string out_dir     = argv[2];

    // 创建输出目录（已存在则忽略错误）
    MKDIR(out_dir.c_str());

    // 打开输入大文件（二进制模式）
    std::ifstream in(input_file.c_str(), std::ios::binary);
    if (!in) {
        std::cerr << "Cannot open input: " << input_file << "\n";
        return 1;
    }

    // 初始化 128 条输出流
    std::vector<std::ofstream> outs;
    outs.reserve(128);
    for (int i = 1; i <= 128; ++i) {
        std::string part = out_dir + "/" + std::to_string(i) + ".bin";
        outs.emplace_back(part.c_str(), std::ios::binary);
        if (!outs.back()) {
            std::cerr << "Cannot open part: " << part << "\n";
            return 1;
        }
    }

    // 位缓冲与计数
    std::vector<uint8_t> bit_buf(128, 0);
    std::vector<int>     bit_cnt(128, 0);
    char chunk[16];

    // 按 16 字节块读取并拆分
    while (in.read(chunk, sizeof(chunk)) || in.gcount() > 0) {  // 块读+gcount :contentReference[oaicite:12]{index=12}:contentReference[oaicite:13]{index=13}
        std::streamsize n = in.gcount();
        for (int byte_idx = 0; byte_idx < n; ++byte_idx) {
            uint8_t byte = static_cast<uint8_t>(chunk[byte_idx]);
            for (int b = 0; b < 8; ++b) {
                int idx = byte_idx * 8 + b;
                uint8_t bit = (byte >> (7 - b)) & 0x1;           // 位提取 :contentReference[oaicite:14]{index=14}
                bit_buf[idx] = (bit_buf[idx] << 1) | bit;
                if (++bit_cnt[idx] == 8) {
                    outs[idx].put(static_cast<char>(bit_buf[idx]));
                    bit_buf[idx] = 0;
                    bit_cnt[idx] = 0;
                }
            }
        }
    }

    // 写剩余未满 8 位的尾部
    for (int i = 0; i < 128; ++i) {
        if (bit_cnt[i] > 0) {
            uint8_t rem = bit_buf[i] << (8 - bit_cnt[i]);
            outs[i].put(static_cast<char>(rem));
        }
    }
    return 0;
}
